# -*- coding: utf-8 -*-
from openpyxl import Workbook
from openpyxl.styles import Border, Side, Alignment, Font
from openpyxl.utils import get_column_letter
from bs4 import BeautifulSoup
import json

# ==================== 配置 ====================
JSON_PATH = "112.json"           # ← 改成你的 JSON 路径
EXCEL_OUT = "table_fixed_final.xlsx"

MIN_ROW_HEIGHT = 30
HEIGHT_PER_LINE = 26
MAX_ROW_HEIGHT = 600
MAX_COL_WIDTH = 60
CHARS_PER_LINE = 28

FONT_NAME = "微软雅黑"
FONT_SIZE = 11
HEADER_BOLD = True
# =============================================

# 读取 JSON
try:
    with open(JSON_PATH, "r", encoding="utf-8") as f:
        data = json.load(f)
    page_data = data[0] if isinstance(data, list) else data
except Exception as e:
    print(f"JSON 读取失败: {e}")
    exit()

table_res = page_data.get("table_res_list", [])
if not table_res:
    print("无表格数据")
    exit()

pred_html = table_res[0].get("pred_html", "")
if not pred_html:
    print("pred_html 为空")
    exit()

# 解析 HTML
soup = BeautifulSoup(pred_html, "html.parser")
wb = Workbook()
ws = wb.active

# 样式
thin = Side(style='thin')
border = Border(left=thin, right=thin, top=thin, bottom=thin)
align = Alignment(wrap_text=True, vertical='center', horizontal='center')
font_normal = Font(name=FONT_NAME, size=FONT_SIZE)
font_header = Font(name=FONT_NAME, size=FONT_SIZE + 1, bold=True)

# ==================== 1. 展开表格：记录每个格子内容 ====================
grid = {}           # (r, c) -> {"text": "", "rowspan":1, "colspan":1}
occupied = {}       # (r, c) -> True (被 rowspan/colspan 占用)

rows = soup.find_all("tr")
max_row = len(rows)
max_col = 0

# 遍历每一行
for r_idx, tr in enumerate(rows, 1):
    c_idx = 1
    for cell in tr.find_all(["td", "th"]):
        # 跳过被占用的格子
        while (r_idx, c_idx) in occupied:
            c_idx += 1

        text = cell.get_text(strip=True)
        rowspan = int(cell.get("rowspan", 1))
        colspan = int(cell.get("colspan", 1))

        # 记录主格子
        grid[(r_idx, c_idx)] = {
            "text": text,
            "rowspan": rowspan,
            "colspan": colspan
        }

        # 标记被占用的格子（包括自己）
        for dr in range(rowspan):
            for dc in range(colspan):
                occupied[(r_idx + dr, c_idx + dc)] = True

        c_idx += colspan

    max_col = max(max_col, c_idx - 1)

# ==================== 2. 写入 Excel（只写左上角） ====================
merge_list = []
col_widths = {}
row_heights = {}

for r in range(1, max_row + 1):
    for c in range(1, max_col + 1):
        if (r, c) not in grid:  # 空白格子
            continue

        info = grid[(r, c)]
        text = info["text"]
        rowspan = info["rowspan"]
        colspan = info["colspan"]

        # 只在左上角写入
        cell = ws.cell(row=r, column=c, value=text)
        cell.alignment = align
        cell.border = border
        cell.font = font_header if r == 1 and HEADER_BOLD else font_normal

        # 记录合并
        if rowspan > 1 or colspan > 1:
            merge_list.append((r, c, r + rowspan - 1, c + colspan - 1))

        # 列宽（中文算2）
        char_cnt = sum(2 if '\u4e00' <= ch <= '\u9fff' else 1 for ch in text)
        avg_width = char_cnt // max(colspan, 1)
        for dc in range(colspan):
            col_idx = c + dc
            col_widths[col_idx] = max(col_widths.get(col_idx, 0), avg_width)

        # 行高
        lines = text.count('\n') + 1
        wrap_lines = max(1, char_cnt // CHARS_PER_LINE + 1)
        total_lines = max(lines, wrap_lines)
        row_heights[r] = max(row_heights.get(r, 0), total_lines * HEIGHT_PER_LINE)

# ==================== 3. 合并单元格（合并后重设样式） ====================
for sr, sc, er, ec in merge_list:
    ws.merge_cells(start_row=sr, start_column=sc, end_row=er, end_column=ec)
    top_left = ws.cell(sr, sc)
    top_left.alignment = align
    top_left.border = border
    top_left.font = font_header if sr == 1 and HEADER_BOLD else font_normal

# ==================== 4. 设置列宽 ====================
for c, width in col_widths.items():
    col_letter = get_column_letter(c)
    adj_width = min((width + 4) / 1.8, MAX_COL_WIDTH)
    ws.column_dimensions[col_letter].width = max(adj_width, 10)

# ==================== 5. 设置行高（宽松） ====================
for r in range(1, ws.max_row + 1):
    base = row_heights.get(r, MIN_ROW_HEIGHT)
    actual_lines = 1
    for cell in ws[r]:
        if cell.value:
            txt = str(cell.value)
            ln = txt.count('\n') + 1
            cn = sum(1 for ch in txt if '\u4e00' <= ch <= '\u9fff')
            wrap = max(1, cn // CHARS_PER_LINE + 1)
            actual_lines = max(actual_lines, ln, wrap)
    final_h = max(MIN_ROW_HEIGHT, actual_lines * HEIGHT_PER_LINE, base)
    ws.row_dimensions[r].height = min(final_h, MAX_ROW_HEIGHT)

# ==================== 6. 冻结首行 ====================
ws.freeze_panes = "A2"

# ==================== 7. 保存 ====================
try:
    wb.save(EXCEL_OUT)
    print(f"\n导出成功！文件: {EXCEL_OUT}")
    print("已完美解决：对齐、合并、换行、行高、列宽")
except Exception as e:
    print(f"保存失败: {e}")